/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package GA;

import java.nio.ByteBuffer;
import tetris.Game;
import tetris.SlightlyLessStupidAI;
import tetris.TetrisAI;

/**
 *
 * @author S094182
 */
public class TetrisEnvironment implements IEnvironment{

    protected int N_GENES;
    protected Game game;
    protected IEvolvingAI ai;
    
    public TetrisEnvironment(Game game){
        this.game = game;
        TetrisAI ai = new SlightlyLessStupidAI(N_GENES);
        game.setAi(ai);
        this.ai = (IEvolvingAI) ai;
        N_GENES = this.ai.getNGenes();
    }
    
    public TetrisEnvironment() {
        N_GENES = ai.getNGenes();
    }
    
    @Override
    public int getGeneLength() {
        return N_GENES * 32;
    }

    @Override
    public int getFitnessType() {
        return BinaryGenome.MAXIMIZE;
    }

    @Override
    public double evaluateGenome(BinaryGenome gene) {
        if (gene.isFitnessSet())
            return gene.getFitness();
        double[] weights = translate(gene.getGenome());
        ai.setHeuristic(weights);
        double score = game.run();
        gene.setFitness(score);
        double fitness = gene.getFitness();
        return fitness;
    }
    
    public double[] translate(byte[] genome){
        double[] weights = new double[N_GENES];
        
        ByteBuffer buf = ByteBuffer.wrap(genome);
        
        for (int i = 0; i < N_GENES; i++) {
            if (i == 0 || i == 2)
                weights[i] = buf.getInt() * (500d/Integer.MAX_VALUE);
            else
                weights[i] = buf.getInt() * (100d/Integer.MAX_VALUE);
        }
        
        return weights;
    }
    
    public Double byteToDouble(byte[] gene) {
        ByteBuffer buf = ByteBuffer.wrap(gene);
        return buf.getDouble();
    }
    
    public byte[] doubleToByte(Double d){
        ByteBuffer buf = ByteBuffer.wrap(new byte[8]);
        buf.putDouble(d);
        return buf.array();
    }
}
